// 赋值运算符
let x;

// 赋值
x = 1


// 加法
x += 2
// 减法
x -= 2
// 乘法
x *= 3
// 除法
x /= 2
// 求余
x %= 2
// 求幂
x **= 2

x = 6
// 左移位赋值
x <<= 2
// 00000000 00000000 00000000 10011000
//                            76543210
// 二进制转10进制，2的（从右往左数位数-1）次方之和

// 右移位赋值
x >>= 3
// 00000000 00000000 00000000 00000000

x = -5
// 无符号右移位赋值
x >>>= 2
// 00000000 00000000 00000000 00000101
// 00111111 11111111 11111111 11111110
//                         98 76543210
let count = 0;
for (let i = 1; i <= 29; i++) {
    count += 2 ** i;
}
console.log(count) // 1073741822

let bStr = '00111111 11111111 11111111 11111110';

function bStrToNumber(bStr) {
    // 思路
    bStr = bStr.replace(/\s+/g, '');
    let count = 0;
    for (let i = 0; i < bStr.length; i++) {
        const index = bStr.length - 1 - i;
        const b = bStr[index];

        if (b === '1') {
            count += 2 ** i;
        }
    }
    return count;
}

bStrToNumber(bStr);

// 按位与 按位且
x &= 2
x = x & 2
// 5 &= 2 = 左边必须是变量
// 5 = 5 & 2
// 00000000 00000000 00000000 00000111
// 00000000 00000000 00000000 00000010

// 按位或
x |= 4
// 00000000 00000000 00000000 00000101
// 00000000 00000000 00000000 00000100

// 按位异或
x ^= 2
// 00000000 00000000 00000000 00000111
// 00000000 00000000 00000000 00000010
// 00000000 00000000 00000000 00000101

// 等于
x == 1
// 不等于
x != 1
// 等价于
x === 1
// 不等价于
x !== 1
// 大于
x > 1
// 大于等于
x >= 1
// 小于
x < 1
// 小于等于
x <= 1

// 求余
6 % 3
// 自增
x++
// 自减
x--
// 一元负值符
+ '3'; // 3
-'3'; // -3
let a = 3;
-a; // -3
// 一元正值符
+"2"; // 2
+true; // 1
+false; // 0

// 指数运算符
2 ** 3; // 2 的 3 次方

// 左移
// 右移
// 无符号右移
// 按位与
// 按位或
// 按位异或

// 按位非

// 00000000 00000000 00000000 00000111
// 11111111 11111111 11111111 11111000

let a = false, b = true;
a && b; // false
a || (b && a); // false
!a; // true

// a 为真 1 为假 2
// 三元 | 三目 | 条件运算符
let c = a ? 1 : 2;

obj = {
    a: 1,
    b: '2',
    c: false,
};
delete obj.a;
console.log('a' in obj); // false
console.log(typeof obj.c); // boolean
console.log(typeof obj.b); // string
console.log(typeof obj.a); // number

class Animal {
}

class Dog extends Animal {
    constructor() {
        super();
    }
}

const dog = new Dog();
const animal = new Animal();
console.log(dog instanceof Dog); // true instance 实例（对象） of 属于 ：xx 对象是否属于 类
console.log(dog instanceof Animal); // true instance 实例（对象） of 属于 ：xx 对象是否属于 类

// ts

// 1.取值
// > 2. 调用（创建对象）
// > 3. 逻辑（! ~ - +）、自增自减（++，--）、typeof、delete
// > 4. 乘、除、取余
// > 5. + 加、- 减
// > 6. 位移运算（左移、右移、无符号右移）
// > 7. 范围运算 > >= < <= in instanceof
// > 8. 相等运算 == != === !==
// > 9. & 按位且
// > 10. ^ 按位异或
// > 11. | 按位或
// > 12. && 逻辑且
// > 13. || 逻辑或
// > 14. ? : 条件（三元）运算
// > 15. 赋值 = += -= *= /= %= <<= >>= >>>= &= ^= |=
// , 谁在前面，谁先执行
// () 分组操作符，括号内的优先执行；括号越深，优先级越高
const a = ((((12 - 4) / 5) - 6) + 8) / 2;

// 从上倒下 从左往右 从里往外

// obj.name; arr[i * 2 + 1]; 直接取值
// new Date() | add(1, 2) 间接取值
//

// this
function Animal2() {
    this.name = 'animal';
}

const animal2 = new Aniaml2();

class Animal3 {
    name = '123';
    constructor() {
        this.name;
    }

    log() {
        this.name;

        const self = this;

        function log2() {
            self.name;
        }
    }
}

const obj = {
    name: '123',
    fn() {
        return this.name;
    }
}

function isNumber(num) {
    return typeof num === 'number' && !isNaN(num) && isFinite(num);
}

console.log(isNumber(1 / 0)); // false;
console.log(isNumber(+'b')); // false
console.log(isNumber(123)); // true
